import random
import numpy as np
import cv2 as cv
import math
from YD_C.COM import globals
import os
import shutil


# 根据给定的半径在宽高范围内随机一个中心点的位置
def rand_center(radius):
    x = random.randint(radius, globals.width - 2 * radius)
    y = random.randint(radius, globals.height - 2 * radius)
    center = (y, x)
    return center


# 根据规定宽高，随机生成像素值生成一张图片
def create_img_random():
    random_array = np.random.randint(0, 256, size=(globals.width, globals.height), dtype=np.uint8)
    new_image = np.where(random_array < 128, 0, random_array)
    return new_image


# 根据给定地址图片的像素分布，绘制出一张图片
def create_img_by_img(filepath):
    # 读取原始图像并转换为灰度图像
    image = cv.imread(str(filepath), cv.IMREAD_GRAYSCALE)
    # 获取原始图像的灰度值分布直方图
    hist = cv.calcHist([image], [0], None, [256], [0, 256])
    # 计算累积直方图
    cdf = hist.cumsum()
    # 归一化累积直方图
    cdf_normalized = cdf / cdf.max()
    # 生成随机数列
    random_values = np.random.rand(image.shape[0] * image.shape[1])
    # 根据灰度值分布对随机数列进行排序
    sorted_values = np.interp(random_values, cdf_normalized, np.arange(0, 256))
    # 将排序后的值重塑为与原始图像相同大小的矩阵
    sorted_image = np.reshape(sorted_values, image.shape).astype(np.uint8)
    return sorted_image


#给圆形添加锯齿
def add_etched_circle(image, center, radius):
    # 创建一个与单通道图像大小相同的掩码
    mask = np.zeros_like(image)
    # cv.circle(mask, center, radius, 255, -1)
    
    # 对圆形掩码边缘添加锯齿效果（保持单通道）
    for y in range(image.shape[0]):
        for x in range(image.shape[1]):
            if mask[y, x] == 255:
                distance = np.sqrt((x - center[0]) ** 2 + (y - center[1]) ** 2)
                if np.abs(distance - radius) < 5:
                    if np.random.randint(0, 2) == 0:
                        mask[y, x] = 0
    # 在掩码区域内生成蚀刻效果（单通道处理）
    etched_area = image.copy()
    for y in range(image.shape[0]):
        for x in range(image.shape[1]):
            if mask[y, x] == 255:
                # 单通道只需调整灰度值
                etched_area[y, x] = np.clip(etched_area[y, x] + np.random.randint(-30, 30), 0, 255)
    # 将蚀刻区域应用到原始图像（单通道无需维度扩展）
    result = np.where(mask == 255, etched_area, image)
    return result


# 高斯平滤波
def add_guassianBlur(img):
    ksize = (5, 5)
    sigma = 0
    return cv.GaussianBlur(img, ksize, sigma)


# 中值滤波
def add_median_filter(img, kernel_size=3):
    filter_image = cv.medianBlur(img, kernel_size)
    return filter_image


# 均值滤波
def add_mean_filter(image, kernel_size=3):
    kernel = np.ones((kernel_size, kernel_size), dtype=np.uint8) / (kernel_size * kernel_size)
    filtered_image = cv.filter2D(image, -1, kernel)
    return filtered_image


# 计算当前点到中心点的距离
def point_to_center_dis(point, center_):
    return math.sqrt(math.pow((point[0] - center_[0]), 2) + math.pow((point[1] - center_[1]), 2))


# 给图片添加噪点 范围为限定的box
def add_salt_noise(img, box, center, radius, noise_size):
    for ii in range(box.xmin, box.xmax):
        for jj in range(box.ymin, box.ymax):
            point_ = [ii, jj]
            if point_to_center_dis(point_, center) <= radius:
                if np.random.rand() < noise_size:
                    if np.random.rand() < 0.8:
                        img[jj, ii] = random.randint(30, 80)
                    else:
                        img[jj, ii] = random.randint(130, 240)


# 给圆环添加椒盐噪点
def add_salt_noise_ring(img, box, center, max_radius, min_radius, noise_size):
    for ii in range(box.xmin, box.xmax):
        for jj in range(box.ymin, box.ymax):
            point_ = [ii, jj]
            if point_to_center_dis(point_, center) <= max_radius:
                if point_to_center_dis(point_, center) >= min_radius:
                    img[jj, ii] = 230
                    if np.random.rand() < noise_size:
                        if np.random.rand() < 0.5:
                            img[jj, ii] = random.randint(0, 100)
                        else:
                            img[jj, ii] = random.randint(130, 255)


# 移动图片到新的目录  参数为  源路径  目标路径  文件、图片起始值
def move_bmp_folder(source_folder, dest_folder, file_start_with):
    source_folder = str(source_folder)  # 源文件夹路径
    destination_folder = str(dest_folder)  # 目标文件夹路径
    # /home/mikoptik/yolov7_test/yolo_v7/circle0801/
    # 确保目标文件夹存在
    if not os.path.exists(destination_folder):
        os.makedirs(destination_folder)
    # 遍历源文件夹中的所有文件
    for filename in os.listdir(source_folder):
        if filename.startswith(str(file_start_with)):
            # 构建源文件路径和目标文件路径
            source_path = os.path.join(source_folder, filename)
            destination_path = os.path.join(destination_folder, filename)

            # 复制文件到目标文件夹中
            shutil.copy2(source_path, destination_path)
    print('已成功复制到新的文件夹！')


# 计算圆环阵中每个单圆的中心点的位置
def calculate_single_circle_centerpoint(center_circle_point, center_circle_radius, single_circle_radius):
    single_center_p = []
    center_single_r = center_circle_radius - single_circle_radius
    # 计算六个圆的圆心的中心点的位置
    p1 = [center_circle_point[0] - center_single_r, center_circle_point[1]]
    p2 = [center_circle_point[0] + center_single_r, center_circle_point[1]]
    p3 = [center_circle_point[0] - center_single_r * math.sin(math.radians(30)),
          center_circle_point[1] + center_single_r *
          math.cos(math.radians(30))]
    p4 = [center_circle_point[0] + center_single_r * math.sin(math.radians(30)),
          center_circle_point[1] + center_single_r *
          math.cos(math.radians(30))]
    p5 = [center_circle_point[0] - center_single_r * math.sin(math.radians(30)),
          center_circle_point[1] - center_single_r *
          math.cos(math.radians(30))]
    p6 = [center_circle_point[0] + center_single_r * math.sin(math.radians(30)),
          center_circle_point[1] - center_single_r *
          math.cos(math.radians(30))]
    single_center_p.append(p1)
    single_center_p.append(p2)
    single_center_p.append(p3)
    single_center_p.append(p4)
    single_center_p.append(p5)
    single_center_p.append(p6)
    return single_center_p


# 在图片中添加斑点
def make_spots_image(img, spotBox):
    for x in range(spotBox.xmin, spotBox.xmax):
        for y in range(spotBox.ymin, spotBox.ymax):
            img[y, x] = 120
